/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd2828.h"
//#include "R69434.h"
//#include "ST7796S__PH035NA_01B.h"
//#include "ST7703__BV055HDE_N47_3Q00.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define  HBPD       40//48
#define  HFPD       40  //16
#define  HSPW       20  //8

#define  VBPD      14//3
#define  VFPD      16 //5
#define  VSPW     4 //8
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_NVIC_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

int _write(int file, char *ptr, int len)
{
	switch (file) {
	case STDOUT_FILENO: // stdout
		HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, 0xff);
		break;
	case STDERR_FILENO: // stderr
		// Send the string somewhere
		break;
	default:
		return -1;
	}
	return len;
}


void DSI_CMD(U8 reg, U8 len){
	GP_COMMAD_PA(reg);W_D(len);
}

void DSI_PA(U8 para){
	W_D(para);
}

void DelayX1ms(U32 time){
	delay_ms(time);
}

void init(void)
{
	W_C(0xb7);
	W_D(0x50); // 50=TX_CLK 70=PCLK
	W_D(0x00); // Configuration Register

	W_C(0xb8);
	W_D(0x00);
	W_D(0x00); // VC(Virtual ChannelID) Control Register

	W_C(0xb9);
	W_D(0x00); // 1=PLL disable
	W_D(0x00);
	// TX_CLK/MS should be between 5Mhz to100Mhz
	W_C(0xBA); // PLL=(TX_CLK/MS)*NS 8228=480M 4428=240M  061E=120M
		   // 4214=240M 821E=360M 8219=300M
	W_D(0x14); // D7-0=NS(0x01 : NS=1)
	W_D(0x42); // D15-14=PLL范围 00=62.5-125 01=126-250 10=251-500
		   // 11=501-1000  DB12-8=MS(01:MS=1)

	W_C(0xBB); // LP Clock Divider LP clock = 400MHz / LPD / 8 = 240 / 8 / 4
		   // = 7.5MHz
	W_D(0x03); // D5-0=LPD=0x1 – Divide by 2
	W_D(0x00);

	W_C(0xb9);
	W_D(0x01); // 1=PLL disable
	W_D(0x00);
	// MIPI lane configuration
	W_C(0xDE); //通道数
	W_D(0x01); // 11=4LANE 10=3LANE 01=2LANE 00=1LANE
	W_D(0x00);

	W_C(0xc9);
	W_D(0x02);
	W_D(0x23); // p1: HS-Data-zero  p2: HS-Data- prepare  --> 8031 issue
	delay_ms(100);

	/*============================================================================*/

	// LCD driver initialization
	W_C(0xB7);
	W_D(0x10); // 10=TX_CLK 30=PCLK
	W_D(0x02);

	W_C(0xBD);
	W_D(0x00);
	W_D(0x00);

	/*============================================================================*/
	/*==========================================LCD
	 * INITIAL========================================================================*/

#if (MTP == 1)

	ST7703_MTP(0, 0);

#endif

	DSI_CMD(0x04, 0xB9); /// Set EXTC
	DSI_PA(0xF1);	     // 1
	DSI_PA(0x12);	     // 2
	DSI_PA(0x83);	     // 3

	DSI_CMD(0x1C, 0xBA); /// Set DSI
	DSI_PA(0x33);	     // 1  // 33 4 lane 32 3 lane
	DSI_PA(0x81);	     // 2
	DSI_PA(0x05);	     // 3
	DSI_PA(0xF9);	     // 4
	DSI_PA(0x0E);	     // 5
	DSI_PA(0x0E);	     // 6
	DSI_PA(0x20);	     // 7
	DSI_PA(0x00);	     // 8
	DSI_PA(0x00);	     // 9
	DSI_PA(0x00);	     // 10
	DSI_PA(0x00);	     // 11
	DSI_PA(0x00);	     // 12
	DSI_PA(0x00);	     // 13
	DSI_PA(0x00);	     // 14
	DSI_PA(0x44);	     // 15
	DSI_PA(0x25);	     // 16
	DSI_PA(0x00);	     // 17
	DSI_PA(0x91);	     // 18
	DSI_PA(0x0A);	     // 19
	DSI_PA(0x00);	     // 20
	DSI_PA(0x00);	     // 21
	DSI_PA(0x02);	     // 22
	DSI_PA(0x4F);	     // 23
	DSI_PA(0xD1);	     // 24
	DSI_PA(0x00);	     // 25
	DSI_PA(0x00);	     // 26
	DSI_PA(0x37);	     // 27

	DSI_CMD(0x02, 0xB8); /// Set ECP
	DSI_PA(0x25);	     // 0x75 for 3 Power Mode,0x25 for Power IC Mode

	DSI_CMD(0x04, 0xBF); /// Set PCR
	DSI_PA(0x02);	     //
	DSI_PA(0x11);
	DSI_PA(0x00);

	DSI_CMD(0x0B, 0xB3); /// SET RGB
	DSI_PA(0x0C);	     // 1 VBP_RGB_GEN 7
	DSI_PA(0x10);	     // 2 VFP_RGB_GEN 0B
	DSI_PA(0x0A);	     // 3 DE_BP_RGB_GEN 1E
	DSI_PA(0x50);	     // 4 DE_FP_RGB_GEN 1E
	DSI_PA(0x03);	     // 5
	DSI_PA(0xFF);	     // 6
	DSI_PA(0x00);	     // 7
	DSI_PA(0x00);	     // 8
	DSI_PA(0x00);	     // 9
	DSI_PA(0x00);	     // 10

	DSI_CMD(0x0A, 0xC0); /// Set SCR
	DSI_PA(0x73);	     // 1
	DSI_PA(0x73);	     // 2
	DSI_PA(0x50);	     // 3
	DSI_PA(0x50);	     // 4
	DSI_PA(0x00);	     // 5
	DSI_PA(0x00);	     // 6
	DSI_PA(0x08);	     // 7
	DSI_PA(0x70);	     // 8
	DSI_PA(0x00);	     // 9

	DSI_CMD(0x02, 0xBC); /// Set VDC
	DSI_PA(0x46);	     // 1 defaut=46

	DSI_CMD(0x02, 0xCC); /// Set Panel
	DSI_PA(0x0B);	     // 1 Forward:0x0B , Backward:0x07

	DSI_CMD(0x02, 0xB4); /// Set Panel Inversion
	DSI_PA(0x80);	     // 1

	DSI_CMD(0x04, 0xB2); /// Set RSO
	DSI_PA(0xC8);	     // 1
	DSI_PA(0x12);	     // 2
	DSI_PA(0x30);	     // 3

	/*DSI_CMD(0x0F, 0xE3); /// Set EQ
	DSI_PA(0x07);	     // 1  PNOEQ
	DSI_PA(0x07);	     // 2  NNOEQ
	DSI_PA(0x0B);	     // 3  PEQGND
	DSI_PA(0x0B);	     // 4  NEQGND
	DSI_PA(0x03);	     // 5  PEQVCI
	DSI_PA(0x0B);	     // 6  NEQVCI
	DSI_PA(0x00);	     // 7  PEQVCI1
	DSI_PA(0x00);	     // 8  NEQVCI1
	DSI_PA(0x00);	     // 9  VCOM_PULLGND_OFF
	DSI_PA(0x00);	     // 10 VCOM_PULLGND_OFF
	DSI_PA(0xFF);	     // 11 VCOM_IDLE_ON
	DSI_PA(0x80);	     // 12
	DSI_PA(0xC0);	     // 13 defaut C0 ESD detect function
	DSI_PA(0x10);	     // 14 SLPOTP*/

	DSI_CMD(0x0D, 0xC1); /// Set POWER
	DSI_PA(0x25);	     // 1 VBTHS VBTLS
	DSI_PA(0x00);	     // 2 E3
	DSI_PA(0x1E);	     // 3 VSPR
	DSI_PA(0x1E);	     // 4 VSNR
	DSI_PA(0x77);	     // 5 VSP VSN
	DSI_PA(0xE1);	     // 6 APS
	DSI_PA(0xFF);	     // 7 VGH1 VGL1
	DSI_PA(0xFF);	     // 8 VGH1 VGL1
	DSI_PA(0xCC);	     // 9 VGH2 VGL2
	DSI_PA(0xCC);	     // 10 VGH2 VGL2
	DSI_PA(0x77);	     // 11 VGH3 VGL3
	DSI_PA(0x77);	     // 12 VGH3 VGL3

	DSI_CMD(0x03, 0xB5); /// Set BGP
	DSI_PA(0x0A);	     // 1 vref
	DSI_PA(0x0A);	     // 2 nvref

	/*DSI_CMD(0x03, 0xB6); /// Set VCOM
	DSI_PA(0x50);	     // 1 F_VCOM
	DSI_PA(0x50);	     // 2 B_VCOM*/

	DSI_CMD(0x40, 0xE9); /// Set GIP
	DSI_PA(0xC2);	     // 1  PANSEL      //04,C4
	DSI_PA(0x10);	     // 2  SHR_0[11:8] //00,10
	DSI_PA(0x0F);	     // 3  SHR_0[7:0]  //04,0F
	DSI_PA(0x00);	     // 4  SHR_1[11:8]
	DSI_PA(0x00);	     // 5  SHR_1[7:0]
	DSI_PA(0xB2);	     // 6  SPON[7:0]   B2
	DSI_PA(0xB8);	     // 7  SPOFF[7:0]  B8
	DSI_PA(0x12);	     // 8  SHR0_1[3:0], SHR0_2[3:0]
	DSI_PA(0x31);	     // 9  SHR0_3[3:0], SHR1_1[3:0]
	DSI_PA(0x23);	     // 10  SHR1_2[3:0], SHR1_3[3:0]
	DSI_PA(0x48);	     // 11  SHP[3:0], SCP[3:0]  48
	DSI_PA(0x8B);	     // 12  CHR[7:0]  //08,8B
	DSI_PA(0xB2);	     // 13  CON[7:0]  B2
	DSI_PA(0xB8);	     // 14  COFF[7:0] B8
	DSI_PA(0x47);	     // 15  CHP[3:0], CCP[3:0]  47
	DSI_PA(0x20);	     // 16  USER_GIP_GATE[7:0]
	DSI_PA(0x00);	     // 17  CGTS_L[21:16]
	DSI_PA(0x00);	     // 18  CGTS_L[15:8]
	DSI_PA(0x30);	     // 19  CGTS_L[7:0]
	DSI_PA(0x00);	     // 20  CGTS_INV_L[21:16]
	DSI_PA(0x00);	     // 21  CGTS_INV_L[15:8]
	DSI_PA(0x00);	     // 22  CGTS_INV_L[7:0]
	DSI_PA(0x00);	     // 23  CGTS_R[21:16]
	DSI_PA(0x00);	     // 24  CGTS_R[15:8]
	DSI_PA(0x30);	     // 25  CGTS_R[7:0]
	DSI_PA(0x00);	     // 26  CGTS_INV_R[21:16]
	DSI_PA(0x00);	     // 27  CGTS_INV_R[15:8]
	DSI_PA(0x00);	     // 28  CGTS_INV_R[7:0]
	DSI_PA(0x02); // 29  COS1_L[3:0],  COS2_L[3:0] ,// CLK_L_1  CLK_L_2
	DSI_PA(0x46); // 30  COS3_L[3:0],  COS4_L[3:0] ,// CLKB_L_1 CLKB_L_2
	DSI_PA(0x02); // 31  COS5_L[3:0],  COS6_L[3:0] ,// STV_L_1  STV_L_2
	DSI_PA(0x88); // 32  COS7_L[3:0],  COS8_L[3:0] ,//
	DSI_PA(0x88); // 33  COS9_L[3:0],  COS10_L[3:0],//
	DSI_PA(0x88); // 34  COS11_L[3:0], COS12_L[3:0],//
	DSI_PA(0x88); // 35  COS13_L[3:0], COS14_L[3:0],//
	DSI_PA(0x88); // 36  COS15_L[3:0], COS16_L[3:0],//
	DSI_PA(0x88); // 37  COS17_L[3:0], COS18_L[3:0],//
	DSI_PA(0x88); // 38  COS19_L[3:0], COS20_L[3:0],//
	DSI_PA(0xF8); // 39  COS21_L[3:0], COS22_L[3:0],// FW BW
	DSI_PA(0x13); // 40  COS1_R[3:0],  COS2_R[3:0] ,// CLK_R_1  CLK_R_2
	DSI_PA(0x57); // 41  COS3_R[3:0],  COS4_R[3:0] ,// CLKB_R_1 CLKB_R_2
	DSI_PA(0x13); // 42  COS5_R[3:0],  COS6_R[3:0] ,// STV_R_1  STV_R_2
	DSI_PA(0x88); // 43  COS7_R[3:0],  COS8_R[3:0] ,//
	DSI_PA(0x88); // 44  COS9_R[3:0],  COS10_R[3:0],//
	DSI_PA(0x88); // 45  COS11_R[3:0], COS12_R[3:0],//
	DSI_PA(0x88); // 46  COS13_R[3:0], COS14_R[3:0],//
	DSI_PA(0x88); // 47  COS15_R[3:0], COS16_R[3:0],//
	DSI_PA(0x88); // 48  COS17_R[3:0], COS18_R[3:0],//
	DSI_PA(0x88); // 49  COS19_R[3:0], COS20_R[3:0],//
	DSI_PA(0xF8); // 50  COS21_R[3:0], COS22_R[3:0],// FW BW
	DSI_PA(0x00); // 51  TCONOPTION
	DSI_PA(0x00); // 52  OPTION
	DSI_PA(0x00); // 53  OTPION
	DSI_PA(0x00); // 54  OPTION
	DSI_PA(0x00); // 55  CHR2
	DSI_PA(0x00); // 56  CON2
	DSI_PA(0x00); // 57  COFF2
	DSI_PA(0x00); // 58  CHP2,CCP2
	DSI_PA(0x00); // 59  CKS 21 20 19 18 17 16
	DSI_PA(0x00); // 60  CKS 15 14 13 12 11 10 9 8
	DSI_PA(0x00); // 61  CKS 7~0
	DSI_PA(0x00); // 62  COFF[7:6]   CON[5:4]    SPOFF[3:2]    SPON[1:0]
	DSI_PA(0x00); // 63  COFF2[7:6]    CON2[5:4]   - - - -

	DSI_CMD(0x3E, 0xEA); /// Set GIP2
	DSI_PA(0x00);	     // 1  ys2_sel[1:0]
	DSI_PA(0x1A);	     // 2  user_gip_gate1[7:0]
	DSI_PA(0x00);	     // 3  ck_all_on_width1[5:0]
	DSI_PA(0x00);	     // 4  ck_all_on_width2[5:0]
	DSI_PA(0x00);	     // 5  ck_all_on_width3[5:0]
	DSI_PA(0x00);	     // 6  ys_flag_period[7:0]
	DSI_PA(0x02);	     // 7  ys_2
	DSI_PA(0x00);	     // 8  user_gip_gate1_2[7:0]
	DSI_PA(0x00);	     // 9  ck_all_on_width1_2[5:0]
	DSI_PA(0x00);	     // 10 ck_all_on_width2_2[5:0]
	DSI_PA(0x00);	     // 11 ck_all_on_width3_2[5:0]
	DSI_PA(0x00);	     // 12 ys_flag_period_2[7:0]
	DSI_PA(0x75);	     // 13 COS1_L[3:0], COS2_L[3:0]   // CLK_L_1 CLK_L_2
	DSI_PA(0x31); // 14 COS3_L[3:0], COS4_L[3:0]   // CLKB_L_1 CLKB_L_2
	DSI_PA(0x31); // 15 COS5_L[3:0], COS6_L[3:0]   // STV_L_1 STV_L_2
	DSI_PA(0x88); // 16 COS7_L[3:0], COS8_L[3:0]
	DSI_PA(0x88); // 17 COS9_L[3:0], COS10_L[3:0]
	DSI_PA(0x88); // 18 COS11_L[3:0], COS12_L[3:0]
	DSI_PA(0x88); // 19 COS13_L[3:0], COS14_L[3:0]
	DSI_PA(0x88); // 20 COS15_L[3:0], COS16_L[3:0]
	DSI_PA(0x88); // 21 COS17_L[3:0], COS18_L[3:0]
	DSI_PA(0x88); // 22 COS19_L[3:0], COS20_L[3:0]
	DSI_PA(0x8F); // 23 COS21_L[3:0], COS22_L[3:0]		  FW   BW
	DSI_PA(0x64); // 24 COS1_R[3:0], COS2_R[3:0]   // CLK_R_1  CLK_R_2
	DSI_PA(0x20); // 25 COS3_R[3:0], COS4_R[3:0]   // CLKB_R_1 CLKB_R_2
	DSI_PA(0x20); // 26 COS5_R[3:0], COS6_R[3:0]   // STV_R_1  STV_R_2
	DSI_PA(0x88); // 27 COS7_R[3:0], COS8_R[3:0]
	DSI_PA(0x88); // 28 COS9_R[3:0], COS10_R[3:0]
	DSI_PA(0x88); // 29 COS11_R[3:0], COS12_R[3:0]
	DSI_PA(0x88); // 30 COS12_R[3:0], COS14_R[3:0]
	DSI_PA(0x88); // 31 COS15_R[3:0], COS16_R[3:0]
	DSI_PA(0x88); // 32 COS17_R[3:0], COS18_R[3:0]
	DSI_PA(0x88); // 33 COS19_R[3:0], COS20_R[3:0]
	DSI_PA(0x8F); // 34 COS21_R[3:0], COS22_R[3:0] // FW BW
	DSI_PA(0x23); // 35 EQOPT , EQ_SEL
	DSI_PA(0x10); // 36 EQ_DELAY[7:0]
	DSI_PA(0x00); // 37 EQ_DELAY_HSYNC [3:0]
	DSI_PA(0x00); // 38 HSYNC_TO_CL1_CNT9[8]
	DSI_PA(0x02); // 39 HSYNC_TO_CL1_CNT9[7:0]
	DSI_PA(0x00); // 40 HIZ_L
	DSI_PA(0x00); // 41 HIZ_R
	DSI_PA(0x00); // 42 CKS_GS[21:16]
	DSI_PA(0x00); // 43 CKS_GS[15:8]
	DSI_PA(0x00); // 44 CKS_GS[7:0]
	DSI_PA(0x00); // 45 CK_MSB_EN[21:16]
	DSI_PA(0x00); // 46 CK_MSB_EN[15:8]
	DSI_PA(0x00); // 47 CK_MSB_EN[7:0]
	DSI_PA(0x00); // 48 CK_MSB_EN_GS[21:16]
	DSI_PA(0x00); // 49 CK_MSB_EN_GS[15:8]
	DSI_PA(0x00); // 50 CK_MSB_EN_GS[7:0]
	DSI_PA(0x00); // 51  SHR2[11:8]
	DSI_PA(0x00); // 52  SHR2[7:0]
	DSI_PA(0x00); // 53  SHR2_1[3:0] SHR2_2
	DSI_PA(0x00); // 54  SHR2_3[3:0]
	DSI_PA(0x00); // 55 SHP1[3:0]
	DSI_PA(0x00); // 56 SPON1[7:0]
	DSI_PA(0x00); // 57 SPOFF1[7:0]
	DSI_PA(0x00); // 58 SHP2[3:0]
	DSI_PA(0x00); // 59 SPON2[7:0]
	DSI_PA(0x00); // 60 SPOFF2[7:0]
	DSI_PA(0x00); // 61 SPOFF2[9:8]/SPON2[9:8]/SPOFF1[9:8]/SPON1[9:8]

	DSI_CMD(0x23, 0xE0); /// Set Gamma
	DSI_PA(0x00);	     // 1
	DSI_PA(0x02);	     // 2
	DSI_PA(0x01);	     // 3
	DSI_PA(0x36);	     // 4
	DSI_PA(0x38);	     // 5
	DSI_PA(0x3F);	     // 6
	DSI_PA(0x2E);	     // 7
	DSI_PA(0x28);	     // 8
	DSI_PA(0x07);	     // 9
	DSI_PA(0x08);	     // 10
	DSI_PA(0x0D);	     // 11
	DSI_PA(0x10);	     // 12
	DSI_PA(0x14);	     // 13
	DSI_PA(0x10);	     // 14
	DSI_PA(0x16);	     // 15
	DSI_PA(0x0E);	     // 16
	DSI_PA(0x0E);	     // 17
	DSI_PA(0x00);	     // 18
	DSI_PA(0x02);	     // 19
	DSI_PA(0x01);	     // 20
	DSI_PA(0x36);	     // 21
	DSI_PA(0x38);	     // 22
	DSI_PA(0x3F);	     // 23
	DSI_PA(0x2E);	     // 24
	DSI_PA(0x28);	     // 25
	DSI_PA(0x07);	     // 26
	DSI_PA(0x08);	     // 27
	DSI_PA(0x0D);	     // 28
	DSI_PA(0x10);	     // 29
	DSI_PA(0x14);	     // 30
	DSI_PA(0x10);	     // 31
	DSI_PA(0x16);	     // 32
	DSI_PA(0x0E);	     // 33
	DSI_PA(0x0E);	     // 34

	DSI_CMD(0x01, 0x11); ////Sleep Out
	DelayX1ms(250);

	DSI_CMD(0x01, 0x29); /// Display On
	DelayX1ms(50);

#if MTP_CHECK == 1

	ST7703_MTP_CHECK();

#endif

	// W_C(0xBF);
	W_C(0x11); //
	// W_D(0x00);     //
	delay_ms(100);

	/*
    #if MTP_CHECK == 1

    ST7703_MTP_CHECK();

    #endif




    #if(MTP == 1)

    ST7703_MTP(0, 0);

    #endif
    */

	W_C(0xBC);
	W_D(0x00);
	W_D(0x00);
	// W_C(0xBF);
	W_C(0x29); //  Display On
	delay_ms(200);

	/*==============================================================================================================================*/

	W_C(0xb7);
	W_D(0x50);
	W_D(0x00); // Configuration Register

	W_C(0xb8);
	W_D(0x00);
	W_D(0x00); // VC(Virtual ChannelID) Control Register

	W_C(0xb9);
	W_D(0x00); // 1=PLL disable
	W_D(0x00);

	W_C(0xBA); // PLL=(TX_CLK/MS)*NS 8228=480M 4428=240M  061E=120M
		   // 4214=240M 821E=360M 8219=300M 8225=444M 8224=432
	W_D(0x28); // D7-0=NS(0x01 : NS=1)
	W_D(0x82); // D15-14=PLL范围 00=62.5-125 01=126-250 10=251-500
		   // 11=501-1000  DB12-8=MS(01:MS=1)

	W_C(0xBB); // LP Clock Divider LP clock = 400MHz / LPD / 8 = 480 / 8/ 8 = 7MHz
	W_D(0x03); // D5-0=LPD=0x1 – Divide by 2
	W_D(0x00);

	W_C(0xb9);
	W_D(0x01); // 1=PLL disable
	W_D(0x00);

	W_C(0xc9);
	W_D(0x02);
	W_D(0x23); // p1: HS-Data-zero  p2: HS-Data- prepare  --> 8031 issue
	delay_ms(10);

	W_C(0xCA);
	W_D(0x01); // CLK Prepare
	W_D(0x23); // Clk Zero

	W_C(0xCB); // local_write_reg(addr=0xCB,data=0x0510)
	W_D(0x10); // Clk Post
	W_D(0x05); // Clk Per

	W_C(0xCC); // local_write_reg(addr=0xCC,data=0x100A)
	W_D(0x05); // HS Trail
	W_D(0x10); // Clk Trail

	W_C(0xD0);
	W_D(0x00);
	W_D(0x00);

	// RGB interface configuration
	W_C(0xB1);
	W_D(HSPW); // HSPW 07
	W_D(VSPW); // VSPW 05

	W_C(0xB2);
	W_D(HBPD); // HBPD 0x64=100
	W_D(VBPD); // VBPD 8 减小下移

	W_C(0xB3);
	W_D(HFPD); // HFPD 8
	W_D(VFPD); // VFPD 10

	W_C(0xB4); // Horizontal active period 720=02D0
	W_D(0xD0); // 013F=319 02D0=720
	W_D(0x02);

	W_C(0xB5); // Vertical active period 1280=0500
	W_D(0x00); // 01DF=479 0500=1280
	W_D(0x05);

	W_C(0xB6); // RGB CLK  16BPP=00 18BPP=01
	W_D(0x07); // D7=0 D6=0 D5=0  D1-0=11 – 24bpp
	W_D(0x20); // D15=VS D14=HS D13=CLK D12-9=NC D8=0=Video with blanking
		   // packet. 00-F0

	// MIPI lane configuration
	W_C(0xDE); //通道数
	W_D(0x03); // 11=4LANE 10=3LANE 01=2LANE 00=1LANE
	W_D(0x00);

	W_C(0xD6); //  05=BGR  04=RGB
	W_D(0x05); // D0=0=RGB 1:BGR D1=1=Most significant byte sent first
	W_D(0x00);

	W_C(0xB7);
	W_D(0x4B);
	W_D(0x02);
}

/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU
	 * Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the
	 * Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_USART1_UART_Init();

	/* Initialize interrupts */
	MX_NVIC_Init();
	/* USER CODE BEGIN 2 */

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	printf("Program Start\r\n");

	// test spi
	/*spi_init();
	while(1)
	{
	  spi_write(SPI_CMD, 0xa5);
	  HAL_Delay(10);
	  spi_write(SPI_DAT, 0x5a);
	  HAL_Delay(10);
	}*/

	spi_init();

	ssd2828_hwreset();

	/*ssd2828_writeReg(0xd4, 0x00, 0xfa);

	uint16_t ssd2828ID = ssd2828_readReg(0xb0);

	printf("read 2828 id = 0x%x\r\n", ssd2828ID);*/

	/*for(uint8_t i = 0xB0; i < 0xff; i++)
	{
	  uint16_t regData = ssd2828_readReg(i);

	  printf("reg(0x%02x) = 0x%04x \r\n", i, regData);
	}*/
	// readMipi()

	// Init_SSD2828(init_ST7703__BV055HDE_N47_3Q00);
	// Init_SSD2828(init_ST7703_BV055HDE_47_IPS_Code);
	init();

	while (1) {
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
		/*HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
		HAL_Delay(1000);
		HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
		HAL_Delay(1000);*/

		// uint8_t dat = 0xa5;
		// HAL_UART_Transmit(&huart1, &dat, 1, 100);
		// HAL_Delay(1000);

		// printf("hello stm32\r\n");
		// HAL_Delay(1000);

		/*HAL_GPIO_TogglePin(LCD_RST_GPIO_Port, LCD_RST_Pin);
		HAL_GPIO_TogglePin(LCD_CS_GPIO_Port, LCD_CS_Pin);
		HAL_GPIO_TogglePin(LCD_MOSI_GPIO_Port, LCD_MOSI_Pin);
		HAL_GPIO_TogglePin(LCD_SCK_GPIO_Port, LCD_SCK_Pin);
		HAL_Delay(1000);*/

		/*if(HAL_GPIO_ReadPin(LCD_MISO_GPIO_Port, LCD_MISO_Pin) ==
		GPIO_PIN_SET)
		{
		  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
		} else {
		  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
		}
		HAL_Delay(200);*/

		printf("Loop...\r\n");
		HAL_Delay(1000);
	}
	/* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

	/** Initializes the CPU, AHB and APB busses clocks
	 */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
	RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
		Error_Handler();
	}
	/** Initializes the CPU, AHB and APB busses clocks
	 */
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK |
				      RCC_CLOCKTYPE_SYSCLK |
				      RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) !=
	    HAL_OK) {
		Error_Handler();
	}
}

/**
 * @brief NVIC Configuration.
 * @retval None
 */
static void MX_NVIC_Init(void)
{
	/* USART1_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(USART1_IRQn);
}

/**
 * @brief USART1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_USART1_UART_Init(void)
{

	/* USER CODE BEGIN USART1_Init 0 */

	/* USER CODE END USART1_Init 0 */

	/* USER CODE BEGIN USART1_Init 1 */

	/* USER CODE END USART1_Init 1 */
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	if (HAL_UART_Init(&huart1) != HAL_OK) {
		Error_Handler();
	}
	/* USER CODE BEGIN USART1_Init 2 */

	/* USER CODE END USART1_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();

	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(GPIOA,
			  LCD_RST_Pin | LCD_CS_Pin | LCD_SCK_Pin | LCD_MOSI_Pin,
			  GPIO_PIN_RESET);

	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(GPIOB, SHUT_Pin | U_CON_Pin, GPIO_PIN_RESET);

	/*Configure GPIO pin : LED_Pin */
	GPIO_InitStruct.Pin = LED_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : LCD_RST_Pin LCD_CS_Pin LCD_SCK_Pin LCD_MOSI_Pin
	 */
	GPIO_InitStruct.Pin =
	    LCD_RST_Pin | LCD_CS_Pin | LCD_SCK_Pin | LCD_MOSI_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	/*Configure GPIO pin : LCD_MISO_Pin */
	GPIO_InitStruct.Pin = LCD_MISO_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(LCD_MISO_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : SHUT_Pin U_CON_Pin */
	GPIO_InitStruct.Pin = SHUT_Pin | U_CON_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
	/* USER CODE BEGIN Error_Handler_Debug */
	/* User can add his own implementation to report the HAL error return
	 * state */

	/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
	/* USER CODE BEGIN 6 */
	/* User can add his own implementation to report the file name and line
	   number,
	   tex: printf("Wrong parameters value: file %s on line %d\r\n", file,
	   line) */
	/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
